package com.hsh.maoduo.service.impl;


import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.hsh.maoduo.common.Result;
import com.hsh.maoduo.constant.ExportPathConstants;
import com.hsh.maoduo.constant.common.DateConstants;
import com.hsh.maoduo.constant.common.GlobalPathConstants;
import com.hsh.maoduo.enums.GoodsStrEnums;
import com.hsh.maoduo.mapper.GoodsMapper;
import com.hsh.maoduo.mapper.OrderGoodsMapper;
import com.hsh.maoduo.pojo.dto.GoodsDTO;
import com.hsh.maoduo.pojo.dto.OrderGoodsDTO;
import com.hsh.maoduo.pojo.entity.Goods;
import com.hsh.maoduo.pojo.entity.OrderGoods;
import com.hsh.maoduo.pojo.export.OrderGoodsExport;
import com.hsh.maoduo.pojo.vo.GoodsVO;
import com.hsh.maoduo.pojo.vo.InboundVO;
import com.hsh.maoduo.pojo.vo.OrderGoodsVO;
import com.hsh.maoduo.pojo.vo.OutboundVO;
import com.hsh.maoduo.service.GoodsService;
import com.hsh.maoduo.service.InboundService;
import com.hsh.maoduo.service.OrderGoodsService;
import com.hsh.maoduo.service.OutboundService;
import com.hsh.maoduo.util.DataUtil;
import com.hsh.maoduo.util.MyBeanUtils;
import com.hsh.maoduo.util.POIExcelUtil;
import org.apache.logging.log4j.util.Strings;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * @author USER
 * @description 针对表【order】的数据库操作Service实现
 * @createDate 2024-01-04 15:31:15
 */
@Service
public class OrderGoodsServiceImpl extends ServiceImpl<OrderGoodsMapper, OrderGoods>
        implements OrderGoodsService {

    @Resource
    private OrderGoodsMapper orderGoodsMapper;

    @Resource
    private GoodsMapper goodsMapper;

    @Resource
    private GoodsService goodsService;
    @Resource
    private InboundService inboundService;
    @Resource
    private OutboundService outboundService;


    @Override
    public List<OrderGoodsDTO> getList(OrderGoodsVO orderGoodsVO) {
        orderGoodsVO.queryInit();
        return orderGoodsMapper.selectListByQuery(orderGoodsVO);
    }

    @Override
    public Integer export(OrderGoodsVO orderGoodsVO) {
        List<OrderGoodsExport> orderGoodsExportList = MyBeanUtils.copyList(getList(orderGoodsVO), OrderGoodsExport.class);
        orderGoodsExportList.stream().forEach(OrderGoodsExport::init);
        String dateRange = DataUtil.removeSpaceAndSymbols(orderGoodsVO.getStartDateTime())
                + "-"
                + DataUtil.removeSpaceAndSymbols(orderGoodsVO.getEndDateTime());
        int rowNum = POIExcelUtil.write(ExportPathConstants.ORDER_PATH_PRE + ExportPathConstants.ORDER_NAME_PRE
                        + dateRange + System.currentTimeMillis() + GlobalPathConstants.XLSX_SUF
                , orderGoodsExportList, OrderGoodsExport.class);
        return rowNum;
    }

    @Override
    public Result<Integer> addList(List<OrderGoodsVO> orderGoodsVOList) {
        List<OutboundVO> outboundVOList = new ArrayList<>();
        return addList(orderGoodsVOList, outboundVOList);
    }

    @Override
    public Result<Integer> addList(List<OrderGoodsVO> orderGoodsVOList, List<OutboundVO> outboundVOList) {
        int insertNum = 0;
        for (OrderGoodsVO orderGoodsVO : orderGoodsVOList) {
            orderGoodsVO.init();
            insertNum += addOne(orderGoodsVO, outboundVOList);
        }
        Integer insertOutNum = outboundService.addList(outboundVOList).getData();
        if (insertOutNum < outboundVOList.size()) {
            log.error("出库部分添加失败:" + insertOutNum + "/" + outboundVOList.size());
        }
        return Result.create(insertNum);
    }

    @Override
    public int addOne(OrderGoodsVO orderGoodsVO, List<OutboundVO> outboundVOList) {
        int insertNum = 0;
        OrderGoods orderGoods = MyBeanUtils.copy(orderGoodsVO, OrderGoods.class);
        try {
            //添加到order表中
            int insert = orderGoodsMapper.insert(orderGoods);
            insertNum += insert;
            //成功添加到order表中之后，插入出库表中，如果名称相同，数量叠加
            if (insert > 0) {
                MyBeanUtils.addListBySimpleName(outboundVOList, orderGoodsVO.orderVOToOutBoundVO(orderGoodsVO.getCreateTime()));
//                MyBeanUtils.addListBySimpleName(outboundVOList, orderGoodsVO.orderVOToOutBoundVO(new Date()));
            }
        } catch (Exception e) {
            log.error(e.getMessage());
        }
        return insertNum;
    }

    @Override
    @Transactional
    public Result update(OrderGoodsVO orderGoodsVO) {
        OrderGoods oldOrderGoods = orderGoodsMapper.selectById(orderGoodsVO.getId());
        if (oldOrderGoods == null) {
            return Result.fail("修改的订单不存在");
        }
        //修改后的商品id --> 查出修改前的商品信息
        Goods oldGoods = goodsMapper.selectById(oldOrderGoods.getGoodsId());
        //修改后的商品id --> 查出修改后的商品信息
        Goods newGoods = goodsMapper.selectById(orderGoodsVO.getGoodsId());

        //订单修改后的商品数量变化,即需要新出库的数量, 新数量-旧数量
        int updateOrderNum = orderGoodsVO.getNum() - oldOrderGoods.getNum();


        //修改了商品id后，对旧商品的处理
        Result updateOldGoods = Result.success();
        if (!Objects.equals(orderGoodsVO.getGoodsId(), oldOrderGoods.getGoodsId()) && oldGoods != null) {
            updateOldGoods = goodsService.update(new GoodsVO()
                    .setId(oldOrderGoods.getGoodsId())
                    .setShopId(orderGoodsVO.getShopId())
                    .setNum(oldGoods.getNum() + oldOrderGoods.getNum()));
            //如果修改了商品id，则新商品数量由0改为修改后的数量
            updateOrderNum = orderGoodsVO.getNum();
        }
        if (newGoods == null) {
            return Result.fail("修改的商品不存在");
        }
        //修改商品id后新商品的处理，和未修改商品id的处理
        Result updateNewGoods = goodsService.update(new GoodsVO()
                .setId(orderGoodsVO.getGoodsId())
                .setShopId(orderGoodsVO.getShopId())
                .setNum(newGoods.getNum() - updateOrderNum));
        //修改订单信息
        if (updateOldGoods.isSuccess() && updateNewGoods.isSuccess()) {
            orderGoodsMapper.updateById(MyBeanUtils.copy(orderGoodsVO, OrderGoods.class));
        }
        return updateNewGoods;
    }


    @Override
    @Transactional
    public Result delete(int id) {
        OrderGoods oldOrderGoods = orderGoodsMapper.selectById(id);
        if (oldOrderGoods == null || oldOrderGoods.getIsDelete().equals(1)) {
            return Result.fail("修改的数据不存在或已删除");
        }
        int insertInbound = inboundService.addOne(new InboundVO()
                .setNo(DateConstants.PURE_DATETIME_MS_FORMAT.format(new Date()))
                .setNum(oldOrderGoods.getNum())
                .setGoodsId(oldOrderGoods.getGoodsId())
                .setSupplierId(9)
                .setNote("删除订单" + oldOrderGoods.getOrderNo())
                .setCreateTime(new Date()));
        if (insertInbound > 0) {
            orderGoodsMapper.updateById(oldOrderGoods.setIsDelete(1));
        }
        return Result.create(insertInbound);
    }

    @Override
    @Transactional(propagation = Propagation.REQUIRES_NEW)
    public int insertByExport(List exportList) {
        //生成订单集合orderGoodsVoList
        List<OrderGoodsVO> orderGoodsVOList = getOrderListByExportList(exportList);
        List<OutboundVO> outboundVOList = new ArrayList<>();
        return addList(orderGoodsVOList, outboundVOList).getData();
    }


    /**
     * 通过导入文件读取的数据 生成订单集合
     *
     * @param exportList
     * @return
     */
    private List<OrderGoodsVO> getOrderListByExportList(List exportList) {
        List<OrderGoodsVO> orderGoodsVOList = new ArrayList<>();
        for (Object export : exportList) {
            //获得每个元素的note 和 goodsName
            Map<String, Object> goodsInfo = MyBeanUtils.objectToMap(export);
            String note = String.valueOf(goodsInfo.get("note"));
            String goodsName = String.valueOf(goodsInfo.get("goodsName"));
            Integer num = goodsInfo.get("num") == null ? 1 : (Integer) goodsInfo.get("num");
            List<GoodsDTO> goodsInfoList = getGoodsInfoList(note);
            if (goodsInfoList.isEmpty()) {
                goodsInfoList = getGoodsInfoList(goodsName);
                goodsInfoList.stream().forEach(v -> v.setNum(v.getNum() * num));
            }

            for (GoodsDTO goodsDTO : goodsInfoList) {
                OrderGoodsVO orderGoodsVO = MyBeanUtils.copy(export, OrderGoodsVO.class);
                //一个订单多种商品时，订单号加'-0,-1,-2'
                if (goodsInfoList.size() > 1) {
                    orderGoodsVO.setOrderNo(orderGoodsVO.getOrderNo() + "-" + goodsInfoList.indexOf(goodsDTO));
                }
                orderGoodsVO.setGoodsName(goodsDTO.getGoodsName());
                orderGoodsVO.setNum(goodsDTO.getNum());
                setGoodsInfoByName(orderGoodsVO);
                orderGoodsVO.setOrderNo(DataUtil.removeSpaceAndSymbols(orderGoodsVO.getOrderNo()));
                orderGoodsVOList.add(orderGoodsVO);
            }
        }
        return orderGoodsVOList;
    }


    private void setGoodsInfoByName(OrderGoodsVO orderGoodsVo) {
        QueryWrapper wrapper = new QueryWrapper();
        wrapper.eq("goods_name", orderGoodsVo.getGoodsName());
        wrapper.or();
        wrapper.eq("simple_goods_name", orderGoodsVo.getGoodsName());
        Goods goods = goodsMapper.selectOne(wrapper);
        if (goods != null) {
            orderGoodsVo.setGoodsId(goods.getId());
            orderGoodsVo.setGoodsName(goods.getGoodsName());
            orderGoodsVo.setSimpleGoodsName(goods.getSimpleGoodsName());
        }
    }

    /**
     * 通过商品信息或者备注，解析出商品列表
     *
     * @param str 商品信息或者备注
     * @return 商品集合
     */
    private List<GoodsDTO> getGoodsInfoList(String str) {
        List<GoodsDTO> goodsInfoList = new ArrayList<>();
        if (Strings.isBlank(str)) {
            return goodsInfoList;
        }
        str = str.trim();
        //去掉备注中的“用户备注：”前缀
        if (str != null) {
            String goodsStr = GoodsStrEnums.BUYER_NOTE.getGoodsStr();
            if (str.startsWith(goodsStr)) {
                str = str.replace(goodsStr, "");
            }
        }
        String[] goodsInfoArray = str.split("\\+|;|；|、|\\s|\\.|。");
        for (String goodsInfo : goodsInfoArray) {
            //格式不为‘任意字符 * 数字 任意字符’，无需解析
            if (!goodsInfo.matches(".*\\*\\d+.*")) {
                continue;
            }
            //只取字符串中 ‘任意字符 * 数字’ 的部分  ，数量后面的字符舍弃
            Matcher matcher = Pattern.compile(".*\\*\\d+").matcher(goodsInfo);
            if (matcher.find()) {
                goodsInfo = matcher.group();
            }

            //多个连续‘*’换成单个‘*’
            goodsInfo = goodsInfo.replaceAll("\\*+", "\\*")
                    //删掉‘*1’或‘*0’
                    .replaceAll("\\*+[01]^\\d*", "");
            if (!goodsInfo.matches(".*\\*\\d+")) {
                goodsInfo = goodsInfo + "*1";
            }
            String[] split = goodsInfo.split("\\*");
            GoodsDTO goodsDTO = new GoodsDTO();
            goodsDTO.setGoodsName(split[0]);
            try {
                goodsDTO.setNum(Integer.parseInt(split[1]));
            } catch (NumberFormatException e) {
                log.error(split[1]);
            }
            goodsInfoList.add(goodsDTO);
        }
        return goodsInfoList;
    }

}




